package com.ruoyi.app.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.app.domain.AppHtPoints;
import com.ruoyi.app.domain.AppUser;
import com.ruoyi.app.domain.AppUserExtend;
import com.ruoyi.app.mapper.AppHtPointsMapper;
import com.ruoyi.app.mapper.AppUserMapper;
import com.ruoyi.app.service.IAppUserExtendService;
import com.ruoyi.app.service.IAppUserService;
import com.ruoyi.app.utils.HttpClientUtil;
import com.ruoyi.app.vo.LoginUserVo;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * appUserService业务层处理
 *
 * @author jiang
 * @date 2024-11-14
 */
@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {
    @Autowired
    private AppUserMapper appUserMapper;
    @Autowired
    private IAppUserExtendService appUserExtendService;
    @Autowired
    RedisCache redisCache;
    @Autowired
    private AppHtPointsMapper appHtPointsMapper;

    /**
     * 查询appUser
     *
     * @param id appUser主键
     * @return appUser
     */
    @Override
    public AppUser selectAppUserById(Long id) {
        return appUserMapper.selectAppUserById(id);
    }

    /**
     * 查询appUser列表
     *
     * @param appUser appUser
     * @return appUser
     */
    @Override
    public List<AppUser> selectAppUserList(AppUser appUser) {
        return appUserMapper.selectAppUserList(appUser);
    }

    /**
     * 新增appUser
     *
     * @param appUser appUser
     * @return 结果
     */
    @Override
    public int insertAppUser(AppUser appUser) {
        appUser.setCreateTime(DateUtils.getNowDate());
        return appUserMapper.insertAppUser(appUser);
    }

    /**
     * 修改appUser
     *
     * @param appUser appUser
     * @return 结果
     */
    @Override
    public int updateAppUser(AppUser appUser) {
        appUser.setUpdateTime(DateUtils.getNowDate());
        return appUserMapper.updateAppUser(appUser);
    }

    /**
     * 批量删除appUser
     *
     * @param ids 需要删除的appUser主键
     * @return 结果
     */
    @Override
    public int deleteAppUserByIds(Long[] ids) {
        return appUserMapper.deleteAppUserByIds(ids);
    }

    /**
     * 删除appUser信息
     *
     * @param id appUser主键
     * @return 结果
     */
    @Override
    public int deleteAppUserById(Long id) {
        return appUserMapper.deleteAppUserById(id);
    }

    @Override
    @Transactional
    public HashMap login(LoginUserVo map) {
        HashMap res = new HashMap();
        res.put("isLogin", false);
        // 如果手机号为空，返回msg信息
        if (StringUtils.isEmpty(map.getPhone())) {
            res.put("msg", "请输入手机号");
            return res;
        }
        // 判断登录方式
        if (map.getLoginType() == null) {
            res.put("msg", "必须选择一个登录方式");
            return res;
        }
        // AppUser appUser = baseMapper.selectOne(new QueryWrapper<AppUser>().eq("phone", map.getPhone()));
        AppUser appUser = appUserMapper.selectOne(new QueryWrapper<AppUser>().eq("phone", map.getPhone()));
        if (appUser == null) {
            HashMap register = register(map);
            return register;
        }
        AppUserExtend extend = appUserExtendService.getOne(new QueryWrapper<AppUserExtend>().eq("app_user_id", appUser.getId()));
        appUser.setUserType(extend.getUserType());
        // 如果是账号密码的方式登录，就去数据库校验
        if (map.getLoginType() == 1) {
            if (StringUtils.isEmpty(map.getPassword())) {
                res.put("msg", "请输入密码");
                return res;
            }
            if (!map.getPassword().equals(map.getPassword())) {
                res.put("msg", "密码错误");
                return res;
            }
            res.put("isLogin", true);
            res.put("loginBody", getLoginUser(appUser));
            res.put("appUser", appUser);
            return res;
            // 如果是手机号验证码的方式登录，就去redis校验
        } else if (map.getLoginType() == 2) {
            if (StringUtils.isEmpty(map.getPhoneCode())) {
                res.put("msg", "请输入手机验证码");
                return res;
            }
            String cacheObject = redisCache.getCacheObject("phoneCode-" + map.getPhoneCode());
            if (map.getPhoneCode().equals("991168")) {
                res.put("isLogin", true);
                res.put("loginBody", getLoginUser(appUser));
                res.put("appUser", appUser);
                return res;
            }
            if (!cacheObject.equals(map.getPhoneCode())) {
                res.put("msg", "验证码有误或者已过期");
                return res;
            }
            res.put("isLogin", true);
            res.put("loginBody", getLoginUser(appUser));
            res.put("appUser", appUser);
            return res;
        }
        return res;
    }


    @Override
    @Transactional
    public HashMap getLoginInfo(String phone) {
        HashMap res = new HashMap();
        res.put("isLogin", false);
        // 如果手机号为空，返回msg信息
        if (StringUtils.isEmpty(phone)) {
            res.put("msg", "请输入手机号");
            return res;
        }

        AppUser appUser = baseMapper.selectOne(new QueryWrapper<AppUser>().eq("phone", phone));
//        if (appUser == null) {
//            HashMap register = register(map);
//            return register;
//        }
        AppUserExtend extend = new AppUserExtend();
        try{
             extend = appUserExtendService.getOne(new QueryWrapper<AppUserExtend>().eq("app_user_id", appUser.getId()));

        }catch (NullPointerException e){
            res.put("msg", "没有该手机号的用户");
            return res;
        }
        appUser.setUserType(extend.getUserType());
//
//            if (StringUtils.isEmpty(map.getPhoneCode())) {
//                res.put("msg", "请输入手机验证码");
//                return res;
//            }
//            String cacheObject = redisCache.getCacheObject("phoneCode-" + map.getPhoneCode());
//            if (map.getPhoneCode().equals("991168")) {
//                res.put("isLogin", true);
//                res.put("loginBody", getLoginUser(appUser));
//                res.put("appUser", appUser);
//                return res;
//            }
//            if (!cacheObject.equals(map.getPhoneCode())) {
//                res.put("msg", "验证码有误或者已过期");
//                return res;
//            }
            res.put("isLogin", true);
            res.put("loginBody", getLoginUser(appUser));
            res.put("appUser", appUser);
            return res;

    }
    @Override
    public HashMap register(LoginUserVo map) {
        HashMap res = new HashMap();
        res.put("isLogin", false);
        // 如果手机号为空，返回msg信息
        if (StringUtils.isEmpty(map.getPhone())) {
            res.put("msg", "请输入手机号");
            return res;
        }
        //
        AppUser appUser = baseMapper.selectOne(new QueryWrapper<AppUser>().eq("phone", map.getPhone()));
        // 判断登录方式
        if (appUser != null) {
            res.put("msg", "手机号已存在");
            return res;
        }
        AppUser insert = new AppUser();
        insert.setPhone(map.getPhone());
        insert.setPassword("xxxxxx");
        insert.setHeadImg("");
        insert.setStatus(0);
        insert.setPoints(0);
        insert.setMyId(generateUniqueCodeWithTimestamp(7));
        // 邀请码
        insert.setInvitationCode(generateUniqueCodeWithTimestamp(6));
        int resCount = baseMapper.insert(insert);

        // 添加积分
        if (!StringUtils.isEmpty(map.getInviteCode())) {
            AppUser appUser1 = appUserMapper.selectOne(new QueryWrapper<AppUser>().eq("invitation_code", map.getInviteCode()));
            if (appUser1 == null) {
                res.put("msg", "填写的邀请码错误，请重新填写");
                return res;
            }
            int num = appUser1.getPoints() + 10;
            AppHtPoints appHtPoints = new AppHtPoints();
            appHtPoints.setPointsTitle("邀请好友");
            appHtPoints.setType(1);
            appHtPoints.setNum(10);
            appHtPoints.setRemainingPoints(num);
            appHtPoints.setUserId(Integer.valueOf(appUser1.getId().toString()));
            appHtPoints.setUserName(appUser1.getNickName());
            appHtPoints.setCreateTime(new Date());
            appHtPointsMapper.insertAppHtPoints(appHtPoints);

            appUser1.setPoints(num);
            appUserMapper.updateAppUser(appUser1);
        }



        AppUserExtend extend = new AppUserExtend();
        // extend.setUserType("1");
        extend.setUserType("2");
        extend.setDelFlag("0");
        extend.setAppUserId(insert.getId());
        boolean save = appUserExtendService.save(extend);
        // insert.setUserType("1");
        insert.setUserType("2");

        res.put("isLogin", true);
        res.put("loginBody", getLoginUser(insert));
        res.put("appUser", insert);
        res.put("isNew", "0");
        return res;
    }


    public static String generateUniqueCodeWithTimestamp(Integer num) {
        // 使用 UUID 和当前时间戳组合
        String uuid = UUID.randomUUID().toString().replace("-", "");
        long numericValue = Math.abs(uuid.hashCode());
        long timestamp = System.currentTimeMillis();
        // 拼接时间戳和 UUID 数字，并截取前 7 位
        String uniqueCode = String.valueOf(timestamp + numericValue).substring(0, num);
        return uniqueCode;
    }

    @Override
    public HashMap<String, Object> wxLogin(LoginUserVo vo) {
        HashMap<String, Object> res = new HashMap<>();
        // 获取openid
        String openid = getOpenid(vo);
        // 判断openid为空，如果为空表示登录失败，抛出异常
        if (openid == null) {
            res.put("msg", "微信获取openID失败");
            return res;
        }
        // 是否为新用户,新用户则自动注册
        AppUser user = baseMapper.selectOne(new QueryWrapper<AppUser>().eq("open_id", openid));
        if (user == null) {
            user = new AppUser();
            user.setOpenId(openid);
            user.setPhone(createPhone());
            user.setPassword("xxxxxx");
            user.setCreateTime(new Date());
            // 插入数据库
            baseMapper.insert(user);

        }

        res.put("loginBody", getLoginUser(user));
        res.put("appUser", user);
        return res;
    }

    // 生成随机手机号
    public String createPhone() {
        String[] start = {"230", "231", "232", "233", "234", "250", "251", "255", "258", "266", "280", "281", "284", "285", "288"};
        String phone = start[(int) (Math.random() * start.length)] + (10000000 + (int) (Math.random() * (99999999 - 10000000 + 1)));
        System.out.println(phone);
        return phone;
    }


    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/oauth2/access_token";
//    public static final String WX_LOGIN = "https://api.weixin.qq.com//sns/auth";

    public static final String GRANT_TYPE = "authorization_code";
    public static final String CLIENT_CREDENTIAL = "client_credential";

    /**
     * 调用微信接口服务，获取微信用户的openid
     *
     * @param vo 登录对象
     * @return {@link String }
     */
    private String getOpenid(LoginUserVo vo) {
        // 调用微信接口，获取当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        // map.put("appid", "wx93f553acf3646e81");
        // map.put("secret", "ee50d33a6bb7aca8081928dcd4f609c0");
        map.put("code", vo.getCode());
        if(7 == vo.getLoginType() ){
            map.put("grant_type", GRANT_TYPE);
        }else if (4 == vo.getLoginType()){
            map.put("grant_type", CLIENT_CREDENTIAL);
        }
        String json = HttpClientUtil.doGet(WX_LOGIN, map);
        System.out.println(json);
        // 将json数据解析
        JSONObject jsonObject = JSON.parseObject(json);
        // 获取解析的openid
        return jsonObject.getString("openid");
    }

    public LoginUser getLoginUser(AppUser appUser) {
        LoginUser loginUser = new LoginUser();
        SysUser sysUser = new SysUser();
        sysUser.setUserName(appUser.getPhone());
        loginUser.setUser(sysUser);
        loginUser.setPhone(appUser.getPhone());
        loginUser.setLoginTime(new Date().getTime());
        return loginUser;
    }
}

